//-------------------------------------------------------------------------------------
// <copyright file="Disconnect.cs" company="Microsoft">
//      Copyright (c) Microsoft Corporation. All rights reserved.
//      THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, 
//      EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED 
//      WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
// </copyright>
// <author>Greg Beech</author>
// <email>gregbee@microsoft.com</email>
// <date>2004-04-20</date>
// <summary>
//      Disconnects from a share.
// </summary>  
//-------------------------------------------------------------------------------------

namespace Microsoft.Sdc.Tasks.Folder.Share
{
    #region Using directives

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Globalization;
    using System.Management;
    using System.Text;

    using Microsoft.Build.Framework;
    using Microsoft.Build.Utilities;

    #endregion

    #region Class Comments
    /// <summary>
    /// Disconnects from a share.
    /// </summary>
    /// <remarks>
    /// <code><![CDATA[<Share.Disconnect ShareName="shareName" Machine="machine" Force="force" />]]></code>
    /// <para>where:</para>
    /// <para><i>shareName (Required)</i></para>
    /// <para>
    /// The name of the share to disconnect from. If the share is redirected to a local device name, e.g. E:
    /// or LPT1: then this argument should be the device name. If the share is not redirected then it should
    /// be the name of the share that was used.
    /// </para>
    /// <para><i>machine</i></para>
    /// <para>
    /// If the share is redirected to a local device name, e.g. E: or LPT1: then this argument must not be
    /// specified. If the share is not redirected then it should be the name of the machine the share is on.
    /// </para>
    /// <para><i>force</i></para>
    /// <para>
    /// Either true or false. If true then the share will be disconnected even if it is in use. The default
    /// is false.
    /// </para>
    /// <seealso cref="Microsoft.Sdc.Tasks.Folder.Share.Create"/>
    /// <seealso cref="Microsoft.Sdc.Tasks.Folder.Share.DeleteShare"/>
    /// <seealso cref="Microsoft.Sdc.Tasks.Folder.Share.Connect"/>
    /// <seealso cref="Microsoft.Sdc.Tasks.Folder.Share.Exists"/>
    /// </remarks>
    /// <example>
    /// <code><![CDATA[
    /// <Project>
    ///     <Target Name="Test">
    ///         <!-- Disconnect from a share redirected to a local device -->
    ///         <Share.Disconnect 
    ///             ShareName="E:"
    ///             Force="true" />
    ///         <!-- Disconnect from a share that is not redirected -->
    ///         <Share.Disconnect 
    ///             ShareName="MyShare"
    ///             Machine="MyMachine"
    ///             Force="true" />
    ///     </Target>
    /// </Project>
    /// ]]></code>    
    /// </example>
    #endregion
    public class Disconnect : ShareTaskBase
    {
        #region Member Variables

        private bool force = false;
        private bool suppressWarnings = false;

        #endregion

        #region Constructors

        /// <summary>
        /// Creates a new task to disconnect from a share.
        /// </summary>
        public Disconnect()
        {
        }

        #endregion

        #region Properties

        /// <summary>
        /// Set to true in order to suppress warnings reported by this task 
        /// </summary>
        /// <value>true or false (defaults to false)</value>
        public bool SuppressWarnings
        {
            get
            {
                return this.suppressWarnings;
            }
            set
            {
                this.suppressWarnings = value;
            }
        }

        /// <summary>
        /// Gets or sets whether the connection is forced to be closed even if it is in use.
        /// </summary>
        /// <value>
        /// <b>true</b> if the connection will be forced to be closed, or <b>false</b> otherwise.
        /// </value>
        public bool Force
        {
            get
            {
                return this.force;
            }

            set
            {
                this.force = value;
            }
        }

        #endregion

        #region Protected Methods

        /// <summary>
        /// Executes the task
        /// </summary>
        protected override void InternalExecute()
        {
            string resourcePath = (this.Machine.Length == 0) ? this.ShareName : this.GetSharePath();
            uint forceLevel = (this.force) ? NativeMethods.USE_LOTS_OF_FORCE : NativeMethods.USE_NOFORCE;
            uint returnCode = NativeMethods.NetUseDel(null, resourcePath, forceLevel);
            switch (returnCode)
            {
                case NativeMethods.NERR_Success:
                    break;
                case NativeMethods.ERROR_NOT_CONNECTED:
                    if (suppressWarnings == false)
                    {
                        this.Log.LogWarning("The machine is not connected to the share so cannot be disconnected.");
                    }
                    break;
                default:
                    throw new Win32Exception((int)returnCode);
            }
        }

        #endregion
    }
}